package com.onpositive.mediawiki.serializing;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import com.onpositive.data.IObjectCollection;
import com.onpositive.data.IPropertyConstants;
import com.onpositive.data.IPropertyMetadata;
import com.onpositive.knowledge.model.IThing;
import com.onpositive.knowledge.model.IUniverse;
import com.onpositive.knowledge.model.impl.MergingProperty;
import com.onpositive.knowledge.model.value.audits.AbstractAuditResult;
import com.onpositive.knowledge.model.values.IHasAuditResult;
import com.onpositive.knowledge.model.values.IHasValue;
import com.onpositive.semantic.model.api.property.IProperty;
import com.onpositive.semantic.model.api.realm.IRealm;
import com.onpositive.units.ParsedValue;


public class UniverseObjectCollection implements IObjectCollection<IThing> {
	

	
	private IRealm<IThing> realm ;
	private IUniverse universe ;
	private IProperty defaultPicturePathProperty ;
	private IProperty defaultPictureLinksProperty ;
	
	
	public UniverseObjectCollection( IUniverse universe, IThing root  )
	{
		this.universe = universe ;
		if( root == null )
			this.realm = this.universe.all() ;
		else
			this.realm = this.universe.getRealm( null, root, null) ;
		
		AbstractAuditResult auditResult = null ;
		if( this.universe instanceof IHasAuditResult )
			auditResult = ((IHasAuditResult)this.universe).getAuditResult() ;
		
		for( IProperty prop : universe.getProperties(null) )
		{
			if( prop.getId().equals( IPropertyConstants.EXTERNAL_DEFAULT_PICTURE_PROPERTY_NAME ) )
			{
				defaultPicturePathProperty = new MergingProperty( prop, auditResult ) ;
				
			}
			if( prop.getId().equals( IPropertyConstants.WWW_PICTURE_LINKS_PROPERTY_NAME ) )
			{
				defaultPictureLinksProperty = new MergingProperty( prop, auditResult ) ;
				
			}
		}
	}

	@Override
	public Iterator<IThing> iterator()
	{
		return this.realm != null ? realm.iterator() : null ;
	}

	@Override
	public Collection<IPropertyMetadata> properties() {
		ArrayList<IPropertyMetadata> result = new ArrayList<IPropertyMetadata>() ;
		

		result.add( new MainPicturePropertyMetadata( defaultPicturePathProperty, defaultPictureLinksProperty) ) ;
		result.add( new PreviewPicturePropertyMetadata( defaultPicturePathProperty, defaultPictureLinksProperty) ) ;
		
		AbstractAuditResult auditResult = null ;
		if( this.universe instanceof IHasAuditResult )
			auditResult = ((IHasAuditResult)this.universe).getAuditResult() ;			
		
		System.out.print("\n\n") ;
		for( IProperty prop : universe.getProperties(null) )
		{
			String pName = prop.getMeta().getSingleValue( IPropertyConstants.CHAR_PROPERTY_NAME_LABEL, String.class, null) ;
			Boolean depricated = prop.getMeta().getSingleValue( IPropertyConstants.CHAR_DEPRICATED_LABEL, Boolean.class, null) ;
			if ( depricated != null && depricated ){
				System.out.print("depricated:" + pName + "\n") ;
				continue ;
			}
//			if( !name.equals( "thrust" ) )
//				continue ;
			
//			if( name.equals(  IPropertyConstants.TEXT_CONTENT_PROPERTY_NAME ) )
//				continue ;			
			
			result.add( new ParsedPropertyMetadata( prop, auditResult ) ) ;
		}				
		
		return result;
	}

	@Override
	public Object getValue( IThing obj, IPropertyMetadata meta) {
		
		if( obj == null )
			return null ;
		if (obj.isDepricated()){
			return null;
		}
		String propertyName = meta.id() ;
		if( propertyName == null )
			return null ;
		
		Object valObj = meta.getValue(obj) ;
		if( valObj == null )
			return null ;
		
		while( valObj instanceof IHasValue ){
			if( valObj instanceof ParsedValue )
				return valObj ;
			
			valObj = ((IHasValue)valObj).value() ;
		}
		
		
		return valObj ;

	}
	
	
	Object getPrimaryValue( IHasValue val )
	{
		Object v1 = val ;
		IHasValue v2 ;
		while( v1 instanceof IHasValue  )
		{
			v2 = (IHasValue) v1 ;
			v1 = v2.value() ;
		}
		
		return v1 ;
	}
	


	@Override
	public int size() {
		return this.realm != null ? realm.size() : 0 ;
	}

	@Override
	public Class<IThing> getObjectClass() {
		return IThing.class ;
	}


}
